package com.i2863.receipt.controller;


import com.i2863.receipt.entity.Activity;
import com.i2863.receipt.entity.Prize;
import com.i2863.receipt.entity.Receipt;
import com.i2863.receipt.entity.Winner;
import com.i2863.receipt.service.ActivityService;
import com.i2863.receipt.service.PrizeService;
import com.i2863.receipt.service.ReceiptService;
import com.i2863.receipt.service.WinnerService;
import com.i2863.receipt.util.CommonPage;
import com.i2863.receipt.util.DateUtils;
import com.i2863.receipt.util.PhoneUtil;
import com.i2863.receipt.util.RandomUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author xuweiwei
 * @Date 2018/6/8.
 */
@RestController
@RequestMapping("/api")
public class ApiController {

    @Autowired
    private ActivityService activityService;

    @Autowired
    private ReceiptService receiptService;

    @Autowired
    private WinnerService winnerService;


    @Autowired
    private PrizeService prizeService;


    @RequestMapping(value = "/activity")
    public Object activity(Integer id, HttpServletRequest req, HttpServletResponse response) throws IOException {
        Activity activity = activityService.findOneById(id);
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        Integer count = receiptService.countByActivityId(id);
        Map<String, Object> map = ApiStatus.SUCCESS.toMap();
        map.put("name", activity.getName());
        map.put("activityStatus", activity.getActivityStatus());
        map.put("amountLow", activity.getAmountLow());
        map.put("startTime", DateUtils.format(activity.getStartTime(), DateUtils.DATE));
        map.put("endTime", DateUtils.format(activity.getEndTime(), DateUtils.DATE));
        map.put("enrollNum", activity.getEnrollNum());
        map.put("insideNum", activity.getInsideNum());
        map.put("num", activity.getNum());
        map.put("outsideNum", activity.getOutsideNum());
        map.put("reselectionNum", activity.getReselectionNum());
        map.put("siteName", activity.getSite().getName());
        map.put("siteImageUrl", activity.getSite().getImgUrl());
        map.put("peopleCount",count);
        return map;

    }

    @RequestMapping(value = "/memberList")
    public Object memberList(Integer id, Integer page, Integer limit, HttpServletRequest req, HttpServletResponse response) throws IOException {
        if (page == null || page < 1) {
            page = 1;
        }
        if (limit == null || limit < 1) {
            limit = 50;
        }
        Activity activity = activityService.findOneById(id);

        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        int count = receiptService.countByActivityId(id);
        if (page > 1 && page > count) {
            page = 1;
        }
        CommonPage pageable = new CommonPage(page, limit, count);
        List<Receipt> receiptList = receiptService.findByActivityId(id, pageable);
        Map<String, Object> result = ApiStatus.SUCCESS.toMap();
        List<Map<String, Object>> memberList = new ArrayList<Map<String, Object>>();
        result.put("pagecount", pageable.getPageCount());
        result.put("page", page);
        for (Receipt receipt : receiptList) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", receipt.getCode());
            map.put("codeNum", receipt.getCodeNum());
            map.put("money", receipt.getMoney());
            map.put("phoneNum", PhoneUtil.hide( receipt.getPhoneNum()));
            map.put("receiptDate", DateUtils.format(receipt.getReceiptDate(), DateUtils.DATE));
            map.put("createDate", DateUtils.format(receipt.getCreateDate(), DateUtils.DATE));
            memberList.add(map);
        }
        result.put("data", memberList);
        result.put("count",memberList.size());
        return result;

    }

    /**
     * 抽出入围用户
     */
    @RequestMapping(value = "/enroll")
    public Object enroll(Integer id, HttpServletRequest req, HttpServletResponse response) throws IOException {

        Activity activity = activityService.findOneById(id);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        //活动已经结束
        if(activity.getActivityStatus() ==Activity.END){
            return ApiStatus.ACTIVITY_STOPED.toMap();
        }
        //活动已经开始
        if (activity.getActivityStatus() != Activity.NOTSTARTED) {
            return ApiStatus.ACTIVITY_STATUS_ERROR.toMap();
        }
        int enrollNum = activity.getEnrollNum();
        int reselectionNum = activity.getReselectionNum();
        int sum = enrollNum + reselectionNum;
        List<Integer> receiptList = receiptService.findByActivityId(id);
        List<Integer> winnerList = RandomUtil.random(receiptList,sum);
        List<Integer>enrollIdList = winnerList.subList(0,enrollNum);
        List<Integer> reselectIdList = winnerList.subList(enrollNum,winnerList.size());
        List<Receipt> enrollList = receiptService.findByIdList(enrollIdList);
        List<Receipt> reselectList = receiptService.findByIdList(reselectIdList);
        List<Winner> winners = winnerService.enroll(activity,enrollList,reselectList);
        List<Map<String,Object>> data = new ArrayList<>();
        for(Winner winner:winners){
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("code", winner.getReceiptCode());
            map.put("codeNum", winner.getReceiptCodeNum());
            map.put("money", winner.getReceiptMoney());
            map.put("phoneNum", PhoneUtil.hide( winner.getWinPhoneNum()));
            map.put("receiptDate", DateUtils.format(winner.getReceiptDate(), DateUtils.DATE));
            data.add(map);
        }
        Map<String,Object> result =  ApiStatus.SUCCESS.toMap();
        result.put("data",data);
        result.put("count",data.size());
        return result;
    }

    /**
     * 查看入围用户
     */
    @RequestMapping(value = "/enrollList")
    public Object enrollList(Integer id, HttpServletRequest req, HttpServletResponse response) throws IOException {
        Activity activity = activityService.findOneById(id);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        List<Winner> winnerList =   winnerService.enrollList(id);
        List<Map<String,Object>> result = new ArrayList<Map<String, Object>>();
        for(Winner winner:winnerList){
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("receiptMoney",winner.getReceiptMoney());
            map.put("receiptCode",winner.getReceiptCode());
            map.put("receiptCodeNum",winner.getReceiptCodeNum());
            map.put("winPhoneNum",PhoneUtil.hide(winner.getWinPhoneNum()));
            map.put("receiptDate",DateUtils.format(winner.getReceiptDate(),DateUtils.DATE));
            result.add(map);
        }
        Map map =  ApiStatus.SUCCESS.toMap();
        map.put("data",result);
        map.put("count",result.size());
        return map;
    }



    /**
     * 抽出场内选手
     */
    @RequestMapping(value = "/inside")
    public Object inside(Integer id, HttpServletRequest req, HttpServletResponse response) throws IOException {

        Activity activity = activityService.findOneById(id);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        //活动已经结束
        if(activity.getActivityStatus() ==Activity.END){
            return ApiStatus.ACTIVITY_STOPED.toMap();
        }
        //活动状态异常
        if (activity.getActivityStatus() != Activity.STARTED) {
            return ApiStatus.ACTIVITY_STATUS_ERROR.toMap();
        }
        int insideNum = activity.getInsideNum();
        List<Winner> winnerList = winnerService.enrollList(id);
        List<Winner>insideList = winnerService.inside(id,winnerList,insideNum);
        List<Map<String,Object>> data = new ArrayList<>();
        for(Winner winner:insideList){
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("receiptMoney",winner.getReceiptMoney());
            map.put("receiptCode",winner.getReceiptCode());
            map.put("receiptCodeNum",winner.getReceiptCodeNum());
            map.put("winPhoneNum",PhoneUtil.hide(winner.getWinPhoneNum()));
            map.put("receiptDate", DateUtils.format(winner.getReceiptDate(), DateUtils.DATE));
            data.add(map);
        }
        Map map =  ApiStatus.SUCCESS.toMap();
        map.put("data",data);
        map.put("count",data.size());
        return map;
    }


    /**
     * 查询所有场内用户
     */
    @RequestMapping(value = "/insideList")
    public Object insideList(Integer id, HttpServletRequest req, HttpServletResponse response) throws IOException {

        Activity activity = activityService.findOneById(id);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        List<Winner> winnerList =   winnerService.insideList(id);
        List<Map<String,Object>> result = new ArrayList<Map<String, Object>>();
        for(Winner winner:winnerList){
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("receiptMoney",winner.getReceiptMoney());
            map.put("receiptCode",winner.getReceiptCode());
            map.put("receiptCodeNum",winner.getReceiptCodeNum());
            map.put("winPhoneNum",PhoneUtil.hide(winner.getWinPhoneNum()));
            map.put("receiptDate",DateUtils.format(winner.getReceiptDate(),DateUtils.DATE));
            result.add(map);
        }
        Map map =  ApiStatus.SUCCESS.toMap();
        map.put("data",result);
        map.put("count",result.size());
        return map;
    }


    /**
     * 查询看所有场外320个用户
     */
    @RequestMapping(value = "/outsideList")
    public Object outsideList(Integer id, HttpServletRequest req, HttpServletResponse response) throws IOException {
        Activity activity = activityService.findOneById(id);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        List<Winner> winnerList =   winnerService.outsideList(id);
        List<Map<String,Object>> result = new ArrayList<Map<String, Object>>();
        for(Winner winner:winnerList){
            Map<String,Object> map = new HashMap<String, Object>();
            map.put("receiptMoney",winner.getReceiptMoney());
            map.put("receiptCode",winner.getReceiptCode());
            map.put("receiptCodeNum",winner.getReceiptCodeNum());
            map.put("winPhoneNum",PhoneUtil.hide(winner.getWinPhoneNum()));
            map.put("receiptDate",DateUtils.format(winner.getReceiptDate(),DateUtils.DATE));
            result.add(map);
        }
        Map map =  ApiStatus.SUCCESS.toMap();
        map.put("data",result);
        map.put("count",result.size());
        return map;
    }

    /**
     * 统计奖项总人数
     * @param prizeList 奖项集合
     * @return 奖项总人数
     */
    public int countPrize(List<Prize> prizeList){
        int count = 0;
        for(Prize prize:prizeList){
            count+=prize.getNumber();
        }
        return count;
    }

    @RequestMapping(value = "/prizeInfo")
    public Object getPrizeInfo(Integer activityId,Integer level,boolean inside,
                          HttpServletRequest req, HttpServletResponse response) {

        //是否场外
        boolean isReselection = !inside;
        //奖项类型
        int prizeRange = inside?Prize.INSIDE:Prize.OUTSIDE;
        Activity activity = activityService.findOneById(activityId);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }

        //查询活动指定等级的奖项
        List<Prize> prizeList = prizeService.findBySiteIdAndPrizeRangeAndLevel(activity.getSite().getId(),prizeRange,level);
        //判断奖项是否存在
        if(prizeList.isEmpty()){
            return ApiStatus.NOT_EXIST_PRIZE.toMap();
        }
        //计算奖项人数
        int  prizeCount = countPrize(prizeList);

        //获取此奖项中奖人数
        int winCount = winnerService.countByActivityIdAndLevelAndIsReselection(activityId,level,isReselection);

        int rest = prizeCount-winCount;
        Map<String,Object> result = ApiStatus.SUCCESS.toMap();
        result.put("prizeCount",prizeCount);
        result.put("winCount",winCount);
        result.put("restCount",rest);
        return result;
    }

    /**
     * 抽奖
     * @param activityId 活动id
     * @param level  等级
     * @param inside 是否场内
     * @param num 抽奖人数
     * @param req   servlet request
     * @param response servlet response
     * @return  中奖用户
     */
    @RequestMapping(value = "/lottery")
    public Object lottery(int activityId,int level,boolean inside,int num,
                        HttpServletRequest req, HttpServletResponse response)  {
        //是否场外
        boolean isReselection = !inside;
        //奖项类型
        int prizeRange = inside?Prize.INSIDE:Prize.OUTSIDE;
        Activity activity = activityService.findOneById(activityId);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        //活动已经结束
        if( Activity.END.equals(activity.getActivityStatus())){
            return ApiStatus.ACTIVITY_STOPED.toMap();
        }
        //活动状态异常
        if (!Activity.SECOND_ROUND.equals(activity.getActivityStatus())) {
            return ApiStatus.ACTIVITY_STATUS_ERROR.toMap();
        }
        //查询活动指定等级的奖项
        List<Prize> prizeList = prizeService.findBySiteIdAndPrizeRangeAndLevel(activity.getSite().getId(),prizeRange,level);
        //判断奖项是否存在
        if(prizeList.isEmpty()){
            return ApiStatus.NOT_EXIST_PRIZE.toMap();
        }
        //计算奖项人数
        int  prizeCount = countPrize(prizeList);
        //判断奖项是否有名额
        if(prizeCount==0){
            return ApiStatus.PRIZE_IS_EMPTY.toMap();
        }
        //获取此奖项中奖人数
        int winCount = winnerService.countByActivityIdAndLevelAndIsReselection(activityId,level,isReselection);

        //判断奖项是否已经全部抽完
        if(winCount>=prizeCount){
            return ApiStatus.PRIZE_IS_EMPTY.toMap();
        }
        //剩余奖项
        int rest = prizeCount-winCount;
        // num=0 即全部抽取
        if(num<=0){
            num=rest;
        }
        // 判断剩余奖项是否少于抽奖人数
        if(rest<num){
            return ApiStatus.PRIZE_NOT_ENOUGH.toMap();
        }
        Map<String,Object> result = ApiStatus.SUCCESS.toMap();
        List<Map<String,Object>>  winnerList = null;
        //判断是否有二级奖项
        if(prizeList.size()==1){
            //没有二级奖项
            winnerList = winnerService.lottery(activity,prizeList.get(0),num,isReselection);
        }else{
            //有二级奖项
            winnerList = winnerService.lotteryMulti(activity,prizeList,num,isReselection);
        }
        result.put("data",winnerList);
        result.put("count",winnerList.size());
        return result;
    }
    /**
     * 抽奖结果查询
     * @param activityId 活动id
     * @param level  等级
     * @param req   servlet request
     * @param response servlet response
     * @return  中奖用户
     */
    @RequestMapping(value = "/lotteryInfo")
    public Object lotteryInfo(int activityId,int level,
                          HttpServletRequest req, HttpServletResponse response)  {
        Activity activity = activityService.findOneById(activityId);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        //查询指定奖项的中奖人员
        List<Winner> winnerList = winnerService.findByActivityIdAndLevel(activityId,level);
        //返回中奖人员信息
        Map<String,Object> result = ApiStatus.SUCCESS.toMap();
        List<Map<String,Object>>  data = new ArrayList<>();
        for(Winner winner:winnerList){
            Map<String,Object> map = new HashMap<String, Object>();
            //基本情况
            map.put("receiptMoney",winner.getReceiptMoney());
            map.put("receiptCode",winner.getReceiptCode());
            map.put("receiptCodeNum",winner.getReceiptCodeNum());
            map.put("winPhoneNum",PhoneUtil.hide(winner.getWinPhoneNum()));
            map.put("receiptDate",DateUtils.format(winner.getReceiptDate(),DateUtils.DATE));
            map.put("isReselection",winner.getIsReselection());
            //获奖情况
            map.put("money", winner.getMoney());
            map.put("level", winner.getLevel());
            map.put("levelName", winner.getLevelName());
            map.put("prize", winner.getPrize());
            map.put("prizeName", winner.getPrizeName());
            data.add(map);
        }
        result.put("data",data);
        result.put("count",data.size());
        return result;
    }

    /**
     * 抽奖结果查询
     * @param activityId 活动id
     * @param level  等级
     * @param inside 是否场内中奖用户
     * @param req   servlet request
     * @param response servlet response
     * @return  中奖用户
     */
    @RequestMapping(value = "/lotteryInfoAs")
    public Object lotteryInfoAs(int activityId,int level,boolean  inside,
                              HttpServletRequest req, HttpServletResponse response)  {
        Activity activity = activityService.findOneById(activityId);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        boolean isReselection = !inside;
        //查询指定奖项的中奖人员
        List<Winner> winnerList = winnerService.findByActivityIdAndLevelAndIsReselection(activityId,level,isReselection);
        //返回中奖人员信息
        Map<String,Object> result = ApiStatus.SUCCESS.toMap();
        List<Map<String,Object>>  data = new ArrayList<>();
        for(Winner winner:winnerList){
            Map<String,Object> map = new HashMap<String, Object>();
            //基本情况
            map.put("receiptMoney",winner.getReceiptMoney());
            map.put("receiptCode",winner.getReceiptCode());
            map.put("receiptCodeNum",winner.getReceiptCodeNum());
            map.put("winPhoneNum",PhoneUtil.hide(winner.getWinPhoneNum()));
            map.put("receiptDate",DateUtils.format(winner.getReceiptDate(),DateUtils.DATE));
            map.put("isReselection",winner.getIsReselection());
            //获奖情况
            map.put("money", winner.getMoney());
            map.put("level", winner.getLevel());
            map.put("levelName", winner.getLevelName());
            map.put("prize", winner.getPrize());
            map.put("prizeName", winner.getPrizeName());
            data.add(map);
        }
        result.put("data",data);
        result.put("count",data.size());
        return result;
    }

    @RequestMapping(value = "/reset")
    public Object reset(Integer id, HttpServletRequest req, HttpServletResponse response) throws IOException {
        Activity activity = activityService.findOneById(id);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        activityService.reset(id);
        return ApiStatus.SUCCESS.toMap();
    }

    @RequestMapping(value = "/resetInside")
    public Object resetInside(Integer id, HttpServletRequest req, HttpServletResponse response) throws IOException {
        Activity activity = activityService.findOneById(id);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
            activityService.resetInside(id);
        return ApiStatus.SUCCESS.toMap();
    }

    @RequestMapping(value = "/resetLottery")
    public Object resetLottery(Integer id, HttpServletRequest req, HttpServletResponse response) throws IOException {
        Activity activity = activityService.findOneById(id);
        //活动不存在
        if (activity == null) {
            return ApiStatus.NOT_EXIST_ACTIVITY.toMap();
        }
        activityService.resetLottery(id);
        return ApiStatus.SUCCESS.toMap();
    }
}
